import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;


public class AgentUC implements Agent
{
	public AgentUC()
	{
		
	}
	public void init(Collection<String> percepts) 
	{
		System.out.println("HELLO EVERYBODY!!! YAY!!!");
		Map map = new Map(percepts);
		Sucky sucky = new Sucky(percepts);
				
		while(map.containsDirt())
		{
			Position prevPos = sucky.getPosition();
			
			sucky = find(sucky, map, CellType.Dirty);
			
			if(sucky.getPosition().equals(prevPos))
			{
				//sucky is stuck, let's just use this path.
				break;
			}
		}
		sucky = find(sucky, map, CellType.Home);
		
		_actions = sucky.getInstructions();
		for(String s : _actions)
			System.out.println(s);
	}
	private Sucky find(Sucky sucky, Map map, CellType cellTarget)
	{
		LinkedList<Sucky> herd = new LinkedList<Sucky>();
		
		map.clearVisited();
		map.visit(sucky.getPosition());
		herd.add(sucky);
		
		while(herd.size() > 0)
		{
			Sucky target = herd.pollFirst();
			LinkedList<Direction> directions = target.getAvailableDirections(map);
			
			for(Direction dir : directions)
			{
				
				Sucky fork = target.forkTo(dir);
				Position pos = fork.getPosition();
				
				map.visit(pos);
				if(map.getAt(pos) == cellTarget)
				{
					if(cellTarget == CellType.Dirty)
					{
						sucky = fork.fork(ActionType.Suck);
						map.cleanCellAt(pos);
					}
					else sucky = fork;
					
					return sucky;
				}
				else addToSortedList(herd, fork);
			}
		}
		return sucky;
	}
	
	private void addToSortedList(LinkedList<Sucky> list, Sucky sucky)
	{
		int cost = sucky.getCost();
		int index = 0;
		Iterator<Sucky> iterator = list.iterator();
		while(iterator.hasNext())
		{
			Sucky target = iterator.next();
			if(target.getCost() >= cost)
			{
				break;
			}
			index++;
		}
		list.add(index, sucky);
	}
	
	private LinkedList<String> _actions;
	private Boolean _givingUp = false;

	public String nextAction(Collection<String> percepts)
	{
		if(_actions != null)
			return _actions.poll();
		else
		{
			Boolean temp = _givingUp;
			_givingUp = true;
			if(temp) return "TURN_OFF";
			else return "TURN_ON";
		}
	}

}
